#include <iostream>
using namespace std;

/*
    问题:
    1.有个继承之后，程序员写代码让父类的指针指向子类的堆空间，delete 父类指针，只会调用父类的析构函数
    解决办法: 用虚析构解决这个问题，把父类的析构函数定义成虚析构即可解决问题
    语法：
    virtual ~类名(){}

    虚函数的底层原理: 很简单跟虚函数（动态联编）跟普通函数（静态联编）区别类似
      父类的析构定义成虚析构: 编译器采用动态联编，看赋值运算的右边
      Animal *p=l;：//父类是虚析构，看右边
      delete p；看右边，右边cl是子类类型，析构子类理所当然先调用子类的析构，再调用父类的析构
    父类的析构不是虚析构：编译器采用静态联编，看赋值运算的左边
      Animal*p=cl；//父类是不是虚析构.看左边
      delete p;看左边，左边p是父类类型，只调用父类的析构，不调用子类
*/

class Animal
{
public:
    Animal()
    {
        cout << "Animal()" << endl;
    }
    virtual ~Animal()
    {
        cout << "~Animal()" << endl;
    }
};

class Cat : public Animal
{
public:
    Cat()
    {
        cout << "Cat()" << endl;
    }
    ~Cat()
    {
        cout << "~Cat()" << endl;
    }
};

int main()
{
    Cat *c1 = new Cat;

    Animal *p = c1;

    // 主动释放内存
    delete p;
    // delete c1;
}